/**
 * 
 */
package cn.agiledata.bank.account.service.impl;

import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import cn.agiledata.bank.account.dao.IAccountDAO;
import cn.agiledata.bank.account.service.AccountSummary;
import cn.agiledata.bank.account.service.IAccountConst;
import cn.agiledata.bank.account.service.IAccountService;
import cn.agiledata.bank.account.util.AccountHistoryObserverInter;
import cn.agiledata.bank.audit.service.AuditService;
import cn.agiledata.bank.common.exception.BusinessException;
import cn.agiledata.bank.common.service.email.EmailActive;
import cn.agiledata.bank.common.service.email.EmailCancel;
import cn.agiledata.bank.common.util.Constant;
import cn.agiledata.bank.common.util.DataTypeUtil;
import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.common.util.ForeDict;
import cn.agiledata.bank.common.util.SecurityUtil;
import cn.agiledata.bank.common.util.StringUtil;
import cn.agiledata.bank.common.util.UniqueIdentityUtil;
import cn.agiledata.bank.common.util.WeatherUtil;
import cn.agiledata.bank.hibernateBean.Account;
import cn.agiledata.bank.hibernateBean.AccountBalance;
import cn.agiledata.bank.hibernateBean.AccountBank;
import cn.agiledata.bank.hibernateBean.AccountCompany;
import cn.agiledata.bank.hibernateBean.AccountGroups;
import cn.agiledata.bank.hibernateBean.AuditOperandType;
import cn.agiledata.bank.hibernateBean.Groups;
import cn.agiledata.bank.hibernateBean.MoneyRole;
import cn.agiledata.bank.hibernateBean.Operator;
import cn.agiledata.bank.hibernateBean.QdTransDetail;
import cn.agiledata.bank.hibernateBean.ScoresHis;
import cn.agiledata.bank.hibernateBean.SubAccount;
import cn.agiledata.bank.hibernateBean.SystemLog;
import cn.agiledata.bank.myspace.exception.MySpaceException;
import cn.agiledata.bank.myspace.service.AuthenticateService;
import cn.agiledata.bank.myspace.service.IMySpaceService;
import cn.agiledata.bank.scores.service.IScoresService;
import cn.agiledata.bank.scores.service.ScoresFactory;
import cn.agiledata.bank.transaction.bean.CapitalDetailBean;

import com.vnv.infrastructure.email.service.IMailService;
import com.vnv.infrastructure.email.service.VNVMail;
import com.vnv.infrastructure.logic.IPBAppFactory;

/**
 * AccountService的当前实现.
 * <p>
 * 该实现是通过在Spring中配置无状态单例
 * 
 * @author 马贤波
 * 
 *         Mar 31, 2006
 */
public class DefaultAccountServiceImpl implements IAccountService, Constant {

	/**
	 * 审核对象类名，用于审核模块找出相关的审核对象类型
	 */
	public static final String AUDIT_OPERAND_CLASS = "AccountCompany";

	/**
	 * 身份证认证的操作类型标志，用户审核模块找出相关的审核对象类型
	 */
	public static final String ACTION_FLAG_ACCOUNTCOMPANY_AUTHENTICATION = Constant.AUTHENTICATION_METHOD_COMPANY;

	private static final String AUTO = "a";

	private static final String MANUAL = "m";

	private static Log log = LogFactory.getLog(DefaultAccountServiceImpl.class);

	private IAccountDAO accountDAO;

	private IMailService notificationService;

	private AuthenticateService authenticateService;

	private AccountHistoryObserverInter ahoi;

	private AuditService auditService;

	public void setAuditService(AuditService auditService) {
		this.auditService = auditService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.agiledata.bank.account.service.impl.III#userActivate(java.lang.String,
	 * java.lang.String)
	 */
	public String userActivate(String email, String activeCode)
			throws MySpaceException {
		if (email == null)
			throw MySpaceException.EMPTY_EMAIL_ERROR;
		if (activeCode == null)
			throw MySpaceException.EMAIL_ACTIVE_EMPTY;
		Account account = null;
		try {
			account = accountDAO.findAccountBySign(email);
		} catch (RuntimeException e) {
			log.error(e);
			throw BusinessException.INFRA_FAILURE;
		}
		if (account == null)
			throw MySpaceException.ACTIVATE_ACCOUNT_NOT_EXIST;
		if ("7".equals(account.getEmStatus()))
			throw MySpaceException.AVTIVETED_ACCOUNT;
		if (account.getActiveCode() == null
				|| !activeCode.equals(account.getActiveCode()))
			throw MySpaceException.EMAIL_ACTIVE_ERROR;
		account.setEmStatus("7");
		ScoresHis sh = null;
		if ("A".equals(account.getAccountType())
				&& StringUtils.isEmpty(account.getMobile())) {
			IScoresService iss = ScoresFactory.getScoresService();
			sh = iss
					.saveScoresHistory(account.getId().toString(), iss
							.getScoresRule("1", account.getId().toString()),
							null, null);
			iss.setIntroduceScores(account);
		}
		WeatherUtil.fillUpdateInfo(account, account.getId().toString());
		accountDAO.updateAccount(account);
		if (sh != null && sh.getScoresAmount().doubleValue() > 0)
			return sh.getScoresAmount().toString();
		else
			return "";
	}

	public String userCancelToEmail(Map form) throws MySpaceException {
		Long accountId = (Long) form.get("accountId");
		String cancelcode = (String) form.get("cancelcode");
		Account account = accountDAO.getAccountById(accountId);
		if (account.getMobActiveCode() == null
				|| !cancelcode.equals(account.getActiveCode())) {
			throw MySpaceException.EMAIL_ACTIVE_ERROR;
		} else {
			account.setEmail("");
			account.setActiveCode("");
			account.setEmStatus("1");
			account.setUpdateUser(String.valueOf(accountId));
			account.setUpdateTime(new Date());
			AuthenticateService ac = (AuthenticateService) IPBAppFactory
					.getObj("authenticateService");
			ac.setMobileTelAuthenticationStatus(account, "3");
			accountDAO.updateAccount(account);
			return "";
		}
	}

	public String userCancelToMob(Map form) throws MySpaceException {
		Long accountId = (Long) form.get("accountId");
		String mobcode = (String) form.get("mobcode");
		Account account = accountDAO.getAccountById(accountId);
		if (account.getMobActiveCode() == null
				|| !mobcode.equals(account.getMobActiveCode())) {
			throw MySpaceException.MOBILE_ACTIVECODE_ERROR;
		} else {
			account.setMobile("");
			account.setMobActiveCode("");
			account.setMobStatus("1");
			account.setUpdateUser(String.valueOf(accountId));
			account.setUpdateTime(new Date());
			AuthenticateService ac = (AuthenticateService) IPBAppFactory
					.getObj("authenticateService");
			ac.setMobileTelAuthenticationStatus(account,
					Constant.AUTHENTICATION_STATUS_UNPASS);
			accountDAO.updateAccount(account);
			return "";
		}
	}

	public String userActivateToMob(Map form) throws MySpaceException {
		String mobile = (String) form.get("mobile");
		String mobcode = (String) form.get("mobcode");
		if (mobile == null || mobcode == null)
			throw MySpaceException.INFORMAL_FORM;
		Account account = null;
		try {
			account = accountDAO.findAccountBySign(mobile);
		} catch (Exception e) {
			log.error(e);
			throw BusinessException.INFRA_FAILURE;
		}
		if (account == null)
			throw MySpaceException.REGISTER_MOBILE_DUPLICATED;
		if ("7".equals(account.getMobStatus()))
			throw MySpaceException.AVTIVETED_ACCOUNT;
		if (account.getMobActiveCode() == null
				|| !mobcode.equals(account.getMobActiveCode()))
			throw MySpaceException.MOBILE_ACTIVECODE_ERROR;
		account.setMobStatus("7");
		ScoresHis sh = null;
		if ("A".equals(account.getAccountType())
				&& StringUtils.isEmpty(account.getMobile())) {
			IScoresService iss = ScoresFactory.getScoresService();
			sh = iss
					.saveScoresHistory(account.getId().toString(), iss
							.getScoresRule("1", account.getId().toString()),
							null, null);
			iss.setIntroduceScores(account);
		}
		AuthenticateService service = (AuthenticateService) IPBAppFactory
				.getObj(ForeDict.SERVICE_AUTHENTICATE);
		service.setMobileTelAuthenticationStatus(account,
				Constant.AUTHENTICATION_STATUS_PASS);
		WeatherUtil.fillUpdateInfo(account, account.getId().toString());
		accountDAO.updateAccount(account);
		if (sh != null) {
			return sh.getScoresAmount().toString();
		} else {
			return "";
		}
	}

	// 判断账户类型
	public boolean accountType(String email) throws BusinessException {
		if (email == null) {
			throw BusinessException.ACTIVATE_FORM_INFORMAL;
		}
		Account account = null;
		try {
			account = this.accountDAO.findAccountBySign(email);
		} catch (RuntimeException e) {
			log.error(e);
			// 数据库操作失败
			throw BusinessException.INFRA_FAILURE;
		}

		if (account == null) {
			// 没有相关记录
			throw BusinessException.ACTIVATE_ACCOUNT_NOT_EXIST;
		}

		if (account.getAccountType().equals(Constant.ACCOUNT_TYPE_BUYER)) {
			return true;
		} else {
			return false;
		}
	}

	// 取出推荐人的accountid
	public Long getIntroductAccountId(String email) throws BusinessException {
		Account account = this.accountDAO.findAccountBySign(email);
		Long id = null;
		if (account != null) {
			id = account.getId();
		}
		return id;
	}

	/**
	 * 登陆
	 * 
	 * @param from
	 *            来源
	 * @param accountSign
	 * @param operatorId
	 * @param password
	 * @return
	 * @throws BusinessException
	 */
	public AccountSummary userLogon(String from, Map map)
			throws BusinessException {
		Account account = null;
		Operator operator = null;
		String username = (String) map.get("username"); // 登陆名或者accountId
		String operatorId = (String) map.get("operatorId"); // 操作员
		String password = (String) map.get("password"); // 密码
		String ip = (String) map.get("ip"); // ip地址
		// 利用绑定到帐户上的卡号登录系统 end edited by wubo 20080218
		try {
			if (from.equals(Constant.CALL_CENTER)) { // 如果是call
				// center方式，则username是accountId
				account = this.accountDAO.findAccountByAccountId(username);
			} else {
				account = this.accountDAO.findAccountBySign(username);
			}
		} catch (RuntimeException e) {
			log.error(e);
			// 数据库操作失败
			throw BusinessException.INFRA_FAILURE;
		}

		if (account == null) {
			// 没有相关记录
			throw BusinessException.LOGON_ACCOUNT_ERROR;
		}
		boolean modify = false;
		//
		SystemLog syslog = accountDAO.getLastLoginSystemLog(account.getId()
				.toString());
		if (syslog != null) {
			if (DateUtil.naturalDaysBetween(syslog.getLoginTime(), new Date()) >= 1) {
				account.setTranAmount(new Double(0.00));
				account.setSumAmount(new Double(0.00));
				modify = true;
			}
		}

		SystemLog errorSyslog = accountDAO.getLastErrorLoginSystemLog(account
				.getId().toString());
		if (errorSyslog != null) {
			if (DateUtil.naturalDaysBetween(errorSyslog.getLoginTime(),
					new Date()) >= 1) {
				if (account.getStatus().equals(
						Constant.ACCOUNT_STATE_LOGIN_LOCK)) { // 如果昨天帐户被锁定,今天就把他改成有效
					account.setStatus(Constant.ACCOUNT_STATE_NORMAL);
				}
				modify = true;
			}
		}

		if (modify) {
			// zln 修正 20071227 修正了用户上次登陆后交易笔数和交易金额不为空，并在一天以后登陆会产生异常的错误。
			// 原因仅定位但未查明，暂时以其他修改account的方法代替。
			IMySpaceService service = (IMySpaceService) IPBAppFactory
					.getObj(IMySpaceService.MGR_ID);
			try {
				service.saveOrUpdateAccount(account, null, null);
			} catch (Exception e) {
				e.printStackTrace();
			}
			// 原调用方法如下
			// accountDAO.updateAccount(account);
			if (from.equals(Constant.CALL_CENTER)) { // 如果是call
				// center方式，则username是accountId
				account = this.accountDAO.findAccountByAccountId(username);
			} else {
				account = this.accountDAO.findAccountBySign(username);
			}
		}

		if (Constant.ACCOUNT_STATE_LOCK.equals(account.getStatus())) {
			// 账户冻结
			throw BusinessException.LOGON_ACCOUNT_LOCK;
		}
		if (Constant.ACCOUNT_STATE_INVALID.equals(account.getStatus())) {
			// 账户无效
			throw BusinessException.LOGON_ACCOUNT_CANCEl;
		}
		if (Constant.ACCOUNT_STATE_LOGIN_LOCK.equals(account.getStatus())) {
			// 账户锁定（不能登录）
			throw BusinessException.LOGON_ACCOUNT_LOGIN_LOCK;
		}

		// 如果是email登陆，查看是否没有激活；
		if (StringUtil.isEmail(username)) {
			if (!Constant.ACCOUNT_STATE_NORMAL.equals(account.getEmStatus())) {
				// 账户没有激活
				throw BusinessException.LOGON_ACCOUNT_NOT_ACTIVE;
			}
		}

		// 如果是email登陆，查看是否没有激活；
		if (StringUtil.isMobile(username)) {
			if (!Constant.ACCOUNT_STATE_NORMAL.equals(account.getMobStatus())) {
				// 账户没有激活
				throw BusinessException.LOGON_ACCOUNT_NOT_ACTIVE;
			}
		}
		
		// 用户密码超时
		Date overDate = DateUtil.addDate(account.getUpdateTime(), 0, 0,
				Constant.PASSWORD_OVERDATE_DAY);
		if (new Date().after(overDate)) {
			throw BusinessException.LOGON_PASSWORD_OVERDATE;
		}
		BusinessException be = null;
		AccountSummary user = null;
		if (Constant.ACCOUNT_TYPE_CORPORATION.equals(account.getAccountType())
				|| Constant.ACCOUNT_TYPE_INITIAL.equals(account
						.getAccountType())) { // 企业用户
			if (from.equals(Constant.CALL_CENTER)) {// ivr 不支持企业用户
				throw BusinessException.CORPORATION_DOES_NOT_SUPPORT;
			}

			// 如果OperatorID是NULL，则证明用户登录时选择类别错误
			if (operatorId == null) {
				throw BusinessException.LOGON_NOT_PERSONAL;
			}

			// 如果企业账户未通过审核
			if (!Constant.ACCOUNT_AUDIT_STATUS_NORMAL.equals(account
					.getAuditStatus())) {
				throw BusinessException.ACCOUNT_AUDIT_STATUS_NOT;
			}
			if (ADMIN_OPERATOR_SIGN.equals(operatorId.trim().toLowerCase())) {
				// 企业管理员，判定是否企业口令
				// 密码过期判断 add by mxb 20120912
				/*
				 * Date overDate = DateUtil.addDate(account.getCreateTime(),
				 * Constant.PASSWORD_OVERDATE_YEAR, 0, 0); if
				 * (account.getCreateTime().after(overDate)) { be =
				 * BusinessException.LOGON_OPERATOR_PASSWORD_ERROR; }
				 */
				// 取消密码验证
				if (!password.equals(account.getLoginPassword())) {
					// be = BusinessException.LOGON_OPERATOR_PASSWORD_ERROR ;
					throw BusinessException.LOGON_ACCOUNT_ERROR;
				}
			} else {
				// 查找企业操作员
				try {
					operator = this.accountDAO.findOperatorByAccount(account,
							operatorId);
				} catch (RuntimeException e) {
					log.error(e);
					// 数据库操作失败
					throw BusinessException.INFRA_FAILURE;
				}

				if (operator == null) {
					// 没有相关记录
					throw BusinessException.LOGON_OPERATOR_NOT_EXIST;
				}
				// 取消密码验证
				if (!password.equals(operator.getLoginPassword())) {
					throw BusinessException.LOGON_ACCOUNT_ERROR;
				}
			}
		} else if (Constant.ACCOUNT_TYPE_BUYER.equals(account.getAccountType())) { // 个人用户
			// 如果OperatorID不是NULL，则证明用户登录时选择类别错误
			if (operatorId != null) {
				throw BusinessException.LOGON_NOT_ENTERPRISE;
			}

			// 个人用户，判定口令,call center取IVR登陆密码,其他方式取密码
			if (from.equals(Constant.CALL_CENTER)) { // 如果是call center方式

				if (IVR_STATUS_NO.equals(account.getIvrStatus())) { // 没有开通IVR功能
					throw BusinessException.IVR_STATUS_NOT;
				}
				// 取消密码验证
				if (!password.equals(account.getIvrLoginPassword())) {
					be = BusinessException.LOGON_ACCOUNT_ERROR;
//					 throw BusinessException.LOGON_PASSWORD_ERROR ;
				}
			} else {
				// 取消密码验证
				if (!password.equals(account.getLoginPassword())) {
					be = BusinessException.LOGON_ACCOUNT_ERROR;
//					 throw BusinessException.LOGON_PASSWORD_ERROR ;
				}
			}
		} else {
			throw BusinessException.INFORMAL_FORM;
		}

		// //////////////记录系统日志///////////////////////
		// 个人用户登录成功和登录密码输错都会记录系统日志
		// 企业用户登录成功会记录系统日志，登录密码出错会直接抛出异常，不会运行到这里
		SystemLog sysLog = new SystemLog();
		sysLog.setAccount(account);
		sysLog.setAccountName(account.getName());
		if (from.equals(Constant.CALL_CENTER)) {
			ip = "callcenter:" + username;
			username = account.getEmail() == null ? account.getMobile()
					: account.getEmail();
		} else if (from.equals(Constant.WAP)) {
			ip = "wap:" + username;
		}
		sysLog.setAccountId(account.getAccountId());
		sysLog.setLoginIp(ip);
		sysLog.setLoginTime(new Date());
		if (be != null) {
			sysLog.setLoginErrReason(Constant.LOGIN_PWD_ERR);
			sysLog.setLoginResult(Constant.LOGIN_RESULT_FAIL);
			sysLog.setRemark(Constant.LOGIN_ERR_REMARK);
		} else {
			sysLog.setLoginResult(Constant.LOGIN_RESULT_SUCCESS);
		}

		this.accountDAO.updateLog(sysLog);
		// //////////////记录系统日志///////////////////////

		user = new AccountSummary(this.accountDAO, account, operator);
		user.setSysLog(sysLog);

		if (be == null) {
			// 登录成功
			return user;
		} else {
			// 登录密码错误，be = BusinessException.LOGON_PASSWORD_ERROR
			if (be.equals(BusinessException.LOGON_ACCOUNT_ERROR)) {
				// 获取账户当天登录密码输错次数
				int currentLoginPwdErr = this.accountDAO
						.getCurrentLoginPwdErrByAccountId(account.getId());

				// 获取登录密码输错次数上限（系统设定，存在sysbook表里，可修改）
				int maxLoginPwdErr = this.accountDAO
						.getMaxLoginPwdErrFromSysBook();

				String errMsg = "";
//				if (currentLoginPwdErr <= maxLoginPwdErr) {
//					errMsg = "密码错误，且当日已累计输错"
//							+ String.valueOf(currentLoginPwdErr) + "次；超过"
//							+ String.valueOf(maxLoginPwdErr)
//							+ "次系统将锁定您的账户，明日才能登录。";
//					throw new BusinessException(errMsg, "0002");
//				} else {
					// 锁定该账户（不能登录）
				if (currentLoginPwdErr > maxLoginPwdErr) {
					this.accountDAO.lockAccountLoginBySign(username);
					errMsg = "密码错误，且当日密码输入错误超过"
							+ String.valueOf(maxLoginPwdErr)
							+ "次，请您于明日登录。如果您有需要立即处理的交易，请及时与客服联系。";
					throw new BusinessException(errMsg, "0007");
				}
				else {
					throw BusinessException.LOGON_PASSWORD_ERROR ;
				}

			} else {
				throw be;
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.agiledata.bank.account.service.impl.III#userLogout(cn.agiledata.bank.account
	 * .service.AccountSummary)
	 */
	public void userLogout(AccountSummary user) throws BusinessException {
		SystemLog sysLog = user.getSysLog();
		if (sysLog != null) {
			sysLog.setLogoutTime(new Date());
			this.accountDAO.updateLog(sysLog);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.agiledata.bank.account.service.impl.III#userRegister(java.lang.String,
	 * java.lang.String, java.lang.String, java.lang.String, java.lang.String,
	 * java.lang.String)
	 */
	public void userRegisterByWap(String loginPassword, String payPassword,
			String mobile, String username) throws BusinessException {

		String userSign = "";

		if (mobile != null) {
			userSign = userSign + mobile;
		}

		Account account = new Account();
		account.setAccountType(ACCOUNT_TYPE_BUYER);
		account.setAccountId(UniqueIdentityUtil.getAccountId(
				Constant.CUSTOMER_REGISTER, Constant.WAP_REGISTER));
		account.setStatus(Constant.ACCOUNT_STATE_NORMAL); // 账户正常使用

		account.setEmail("");
		account.setName(username);

		WeatherUtil.fillCreateAndUpdateInfo(account, "-");

		// 设置激活码
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		// 设置密码
		if (loginPassword == null) {
			loginPassword = UniqueIdentityUtil.createLoginPass();
		}
		if (payPassword == null) {
			payPassword = UniqueIdentityUtil.createPayPass();
		}
		if (mobile != null) {
			account.setMobile(mobile);
		}
		account.setLoginPassword(SecurityUtil.encryptoMD5String(loginPassword));
		account.setPayPassword(SecurityUtil.encryptoMD5String(payPassword));
		// 通过激活码首字母确定是否自动生成密码
		if (loginPassword == null || payPassword == null) {
			activeCode = AUTO + activeCode;
		} else {
			activeCode = MANUAL + activeCode;
		}
		account.setActiveCode(activeCode);

		this.accountDAO.createAccount(account);

		WeatherUtil
				.fillCreateAndUpdateInfo(account, account.getId().toString());

		SubAccount subNormal = new SubAccount();
		subNormal.setAccount(account);
		subNormal.setSubAccountType(Constant.SUB_ACCOUNT_TYPE_NORMAL);
		account.getSubAccounts().add(subNormal);

		subNormal.setAccountId(UniqueIdentityUtil.getSubAccountId(account
				.getAccountId()));
		subNormal.setAccountName(INIT_SUBACCOUNT_NAME);
		subNormal.setValidFlag("Y");
		subNormal.setIvrFlag("N");
		subNormal.setRemark(INIT_SUBACCOUNT_REMARK);
		WeatherUtil.fillCreateAndUpdateInfo(subNormal, account.getId()
				.toString());

		AccountBalance balance = new AccountBalance();
		balance.setBalance(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		WeatherUtil
				.fillCreateAndUpdateInfo(balance, account.getId().toString());

		balance.setSubAccount(subNormal);
		subNormal.setAccountBalance(balance);
		// add by cjh
		subNormal.setDetailFlag(DETAIL_FLAG_TRUE);

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		SubAccount subMobile = new SubAccount();
		subMobile.setAccount(account);
		subMobile.setSubAccountType(Constant.SUB_ACCOUNT_TYPE_MOBILE);
		account.getSubAccounts().add(subMobile);

		subMobile.setAccountId(UniqueIdentityUtil.getSubAccountId(account
				.getAccountId()));
		subMobile.setAccountName(INIT_SUBACCOUNT_MOBILE);
		subMobile.setValidFlag("Y");
		subNormal.setIvrFlag("N");
		subMobile.setRemark(INIT_SUBACCOUNT_REMARK);
		WeatherUtil.fillCreateAndUpdateInfo(subMobile, account.getId()
				.toString());
		subMobile.setDetailFlag(DETAIL_FLAG_FALSE);

		balance = new AccountBalance();
		balance.setBalance(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));

		WeatherUtil
				.fillCreateAndUpdateInfo(balance, account.getId().toString());

		balance.setSubAccount(subMobile);
		// balance.setMainAccountSeq(new Long("-1")) ;
		subMobile.setAccountBalance(balance);

		account.setDefaultSubAccount(subNormal);

		IScoresService iss = ScoresFactory.getScoresService();
		iss.saveScoresHistory(account.getId().toString(), iss.getScoresRule(
				Constant.SCORES_SOURCE_A, account.getId().toString()), null,
				null);
		this.accountDAO.updateAccount(account);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.agiledata.bank.account.service.impl.III#userRegister(java.lang.String,
	 * java.lang.String, java.lang.String, java.lang.String, java.lang.String,
	 * java.lang.String)
	 */
	public void userRegister(String from, String project, Map map)
			throws BusinessException {
		/** 提取参数* */
		String email = (String) map.get("email");
		String mobile = (String) map.get("mobile");
		String type = (String) map.get("type");
		String corpName = (String) map.get("corpName");
		String corpTel = (String) map.get("corpTel");
		String corpLicenceNo = (String) map.get("corpLicenceNo");
		String corpFinanceName = (String) map.get("corpFinanceName");
		String corpAccountLicenceNo = (String) map.get("corpAccountLicenceNo");
		String corpOrganizeNo = (String) map.get("corpOrganizeNo");
		String corpZip = (String) map.get("corpZip");
		String corpAddr = (String) map.get("corpAddr");
		String corpTaxId = (String) map.get("corpTaxId");
		String loginPassword = (String) map.get("loginPassword");
		String payPassword = (String) map.get("payPassword");
		String name = (String) map.get("name");
		String personname = (String) map.get("personName");
		String sex = (String) map.get("gender");
		String idCardNo = (String) map.get("idCardNo");
		String question = (String) map.get("question");
		String answer = (String) map.get("answer");
		String url = (String) map.get("url");
		String intrEmail = (String) map.get("intremail"); // 介绍人
		String prinName = (String) map.get("prinName");// 法人代表姓名
		String corpBossId = (String) map.get("corpBossId");// 法人代表身份证号码
		Double capitalAmount = (Double) map.get("capitalAmount");// 注册资金
		InputStream idcardPhotoStream = (InputStream) map.get("idcardPhoto");// 身份证正面图片
		InputStream idcardPhotoBackStream = (InputStream) map
				.get("backOfIdcardPhoto");// 身份证反面图片
		InputStream cardPhotoStream = (InputStream) map.get("cardphoto");
		/** 提取参数* */

		if (this.checkRepeat(email, mobile)) { // 判断email或者手机是否重复
			throw BusinessException.REGISTER_ACCOUNT_DUPLICATED;
		}

		if (this.checkType(type)) {
			// 必须是企业或个人之一
			throw BusinessException.REGISTER_FORM_INFORMAL;
		}

		Long introId = null;
		if (StringUtils.isNotEmpty(intrEmail)) {
			if (this.getIntroductAccountId(intrEmail) == null) {
				throw BusinessException.REGISTER_INTRODUCE_EMAIL;
			} else {
				introId = this.getIntroductAccountId(intrEmail);
			}
		}

		String userSign = "-";
		if (email != null) {
			userSign = email + userSign;
		}
		if (mobile != null) {
			userSign = userSign + mobile;
		}

		Account account = new Account();
		account.setAccountType(type);
		account.setAccountId(UniqueIdentityUtil.getAccountId(
				Constant.CUSTOMER_REGISTER, Constant.WEB_REGISTER));
		account.setStatus(Constant.ACCOUNT_STATE_NORMAL); // 帐户状态为正常帐户

		account.setEmail(email);
		account.setGender(sex);
		account.setIdCode(idCardNo);
		if (!StringUtils.isEmpty(personname)) {
			account.setName(personname);
		} else {
			account.setName("");
		}
		account.setIntroduceAccountId(introId);
		account.setQuestion(question);
		account.setAnswer(answer);
		WeatherUtil.fillCreateAndUpdateInfo(account, "-");
		if (Constant.ACCOUNT_TYPE_CORPORATION.equals(type)) {
			// 企业用户，需要企业资料
			AccountCompany ac = new AccountCompany();
			ac.setAccount(account);
			account.setName(corpName);
			ac.setCompanyName(corpName);
			ac.setLinkTel(corpTel);
			ac.setLicenceNo(corpLicenceNo);
			ac.setRegiAddr(corpAddr);
			ac.setRegiZip(corpZip);
			ac.setFinanceName(corpFinanceName);
			ac.setAccountLicenceNo(corpAccountLicenceNo);
			ac.setOrganizeNo(corpOrganizeNo);
			ac.setTaxId(corpTaxId);
			ac.setB2cable("0");
			// 法人代表姓名
			ac.setPrinName(prinName);
			// 法人代表身份证号
			ac.setBossId(corpBossId);
			// 注册资金
			ac.setCapitalAmount(capitalAmount);
			account.setAuditStatus("0"); // 企业的审核状态
			account.setAccountCompany(ac);
		}

		if (email == null || email.trim().length() == 0) {
			account.setEmStatus(Constant.ACCOUNT_STATE_INVALID); // email状态为账户无效
		} else {
			account.setEmStatus(Constant.ACCOUNT_STATE_UNACTIVATED); // email状态为账户尚未激活
		}
		// 设置激活码
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		// 设置密码
		if (loginPassword == null) {
			loginPassword = UniqueIdentityUtil.createLoginPass();
		}
		if (payPassword == null) {
			payPassword = UniqueIdentityUtil.createPayPass();
		}
		if (mobile != null) {
			account.setMobile(mobile);
			if (StringUtil.isStrEmpty(name)) {
				// account.setName(mobile);
			} else {
				// account.setName(name);
			}
			// account.setMobStatus(Constant.ACCOUNT_STATE_UNACTIVATED);
			// //手机状态为账户尚未激活
			account.setMobStatus(Constant.ACCOUNT_STATE_NORMAL); // 手机状态为正常使用
		} else {
			account.setMobStatus(Constant.ACCOUNT_STATE_INVALID); // 手机状态为账户无效
		}
		account.setLoginPassword(SecurityUtil.encryptoMD5String(loginPassword));
		account.setPayPassword(SecurityUtil.encryptoMD5String(payPassword));
		// 通过激活码首字母确定是否自动生成密码
		if (loginPassword == null || payPassword == null) {
			activeCode = AUTO + activeCode;
		} else {
			activeCode = MANUAL + activeCode;
		}
		account.setActivateStatus(Constant.SCORES_ACTIVATE_STATUS_A);
		account.setActiveCode(activeCode);
		account.setIvrStatus(Constant.IVR_STATUS_NO); // 默认关闭IVR账户
		// account.setGrading(this.accountDAO.getGrading(Long.valueOf(Constant.LIMIT_TYPE_DEFAULT)));
		// //设置为普通客户
		account.setSumAmount(new Double(0)); // 单天交易累计额=0
		if (mobile != null) { // 手机注册的话，设置手机认证通过状态
			authenticateService.setMobileTelAuthenticationStatus(account,
					Constant.AUTHENTICATION_STATUS_PASS);

		}
		if (idcardPhotoStream != null) {
			this.accountDAO.createAccount(account, idcardPhotoStream,
					idcardPhotoBackStream, cardPhotoStream);
		} else {
			this.accountDAO.createAccount(account);
		}
		/*
		 * if (Constant.ACCOUNT_TYPE_CORPORATION.equals(type)) {
		 * AuditOperandType aot = getAuditOperandType(); // 若本操作未设置审核规则 if
		 * (!this.auditService.requiredSystemAudit(aot)) { throw
		 * BusinessException.ACCOUNTCOMPANY_AUTHENTICATION; } try {
		 * this.auditService.submit(aot, account.getId().longValue(), account,
		 * true); } catch (AuditException e1) { throw
		 * BusinessException.ACCOUNTCOMPANY_AUTHENTICATION; } }
		 */
		String accountId = account.getId().toString();
		WeatherUtil.fillCreateAndUpdateInfo(account, accountId);
		SubAccount subNormal = new SubAccount();
		subNormal.setAccount(account);
		subNormal.setSubAccountType(Constant.SUB_ACCOUNT_TYPE_NORMAL);
		account.getSubAccounts().add(subNormal);

		subNormal.setAccountId(UniqueIdentityUtil.getSubAccountId(account
				.getAccountId()));
		subNormal.setAccountName(INIT_SUBACCOUNT_NAME);
		subNormal.setValidFlag("Y");
		subNormal.setIvrFlag("N");
		subNormal.setRemark(INIT_SUBACCOUNT_REMARK);

		WeatherUtil.fillCreateAndUpdateInfo(subNormal, accountId);

		AccountBalance balance = new AccountBalance();
		balance.setBalance(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));

		WeatherUtil.fillCreateAndUpdateInfo(balance, accountId);

		balance.setSubAccount(subNormal);
		subNormal.setAccountBalance(balance);
		// add by cjh
		subNormal.setDetailFlag(DETAIL_FLAG_TRUE);
		subNormal.setIvrFlag(IVR_SUBACCOUNT_NO); // 不是IVR子账户

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		SubAccount subMobile = new SubAccount();
		subMobile.setAccount(account);
		subMobile.setSubAccountType(Constant.SUB_ACCOUNT_TYPE_MOBILE);
		account.getSubAccounts().add(subMobile);

		subMobile.setAccountId(UniqueIdentityUtil.getSubAccountId(account
				.getAccountId()));
		subMobile.setAccountName(INIT_SUBACCOUNT_MOBILE);
		subMobile.setValidFlag("Y");
		subMobile.setIvrFlag("N");
		subMobile.setRemark(INIT_SUBACCOUNT_REMARK);
		WeatherUtil.fillCreateAndUpdateInfo(subMobile, accountId);
		subMobile.setDetailFlag(DETAIL_FLAG_FALSE);
		subMobile.setIvrFlag(IVR_SUBACCOUNT_NO); // 不是IVR子账户

		balance = new AccountBalance();
		balance.setBalance(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		balance.setLockAmount(Double.valueOf("0.0"));
		WeatherUtil.fillCreateAndUpdateInfo(balance, accountId);

		balance.setSubAccount(subMobile);
		subMobile.setAccountBalance(balance);

		account.setDefaultSubAccount(subNormal);

		List ls = this.accountDAO.findDefaultGroup();
		if (ls.size() > 0) {
			Set accountGroups = new HashSet();
			for (Iterator iter = ls.iterator(); iter.hasNext();) {
				AccountGroups accGroup = new AccountGroups();
				accGroup.setAccount(account);
				accGroup.setGroups((Groups) iter.next());
				WeatherUtil.fillCreateAndUpdateInfo(accGroup, "-");
				accountGroups.add(accGroup);
				ahoi.updateAccountGroupHis(accGroup);
			}
			account.setAccountGroupses(accountGroups);
		}

		this.accountDAO.updateAccount(account);

		if (mobile != null) { // 注册手机用户，加积分
			ScoresHis sh = null;
			// 计算积分
			IScoresService iss = ScoresFactory.getScoresService();
			sh = iss.saveScoresHistory(account.getId().toString(), iss
					.getScoresRule(Constant.SCORES_SOURCE_A, account.getId()
							.toString()), null, null);
			iss.setActivationStatus(account.getId());
		}
		if (!StringUtil.isStrEmpty(email)) {
			VNVMail mail = VNVMail.createActivateMail(url, email, activeCode,
					loginPassword, payPassword, project);
			this.notificationService.sendMail(mail);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.agiledata.bank.account.service.impl.III#checkEmail(java.lang.String)
	 */
	private boolean checkRepeat(String email, String mobile)
			throws BusinessException {
		int count = 0;
		if (email != null) {
			count = this.accountDAO.findCountByEmail(email);
		}
		if (mobile != null) {
			count += this.accountDAO.findCountByEmail(mobile);
		}

		return count != 0;

	}

	private boolean checkType(String type) {
		if (type == null
				|| !(Constant.ACCOUNT_TYPE_BUYER.equals(type) || Constant.ACCOUNT_TYPE_CORPORATION
						.equals(type))) {
			// 必须是企业或个人之一
			return true;
		} else {
			return false;
		}
	}

	public void sendActivateMailAfterRegister(String email, String paypass,
			Long accountId) throws BusinessException {
		Account account = accountDAO.findAccountBySign(email);
		if (account != null)
			throw BusinessException.REGISTER_ACCOUNT_DUPLICATED;
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		account = accountDAO.getAccountById(accountId);
		String loginPassword = account.getLoginPassword();
		String payPassword = account.getPayPassword();
		if (loginPassword == null)
			loginPassword = UniqueIdentityUtil.createLoginPass();
		if (payPassword == null)
			payPassword = UniqueIdentityUtil.createPayPass();
		if (loginPassword == null || payPassword == null)
			activeCode = "a" + activeCode;
		else
			activeCode = "m" + activeCode;
		if (!payPassword.equals(paypass)) {
			throw BusinessException.VERIFYCODE_INVALID;
		} else {
			account.setEmStatus("2");
			account.setEmail(email);
			account.setActiveCode(activeCode);
			account.setUpdateUser(String.valueOf(accountId));
			account.setUpdateTime(new Date());
			accountDAO.updateAccount(account);
			VNVMail mail = VNVMail.createActivateMail(email, activeCode,
					loginPassword, payPassword, "");
			notificationService.sendMail(mail);
			System.out.println("开通email..发激活信..");
			return;
		}
	}

	public void sendActivateMailAfterRegister(Map map) throws MySpaceException {
		String urlPath = (String) map.get("urlPath");
		Long accountId = (Long) map.get("accountId");
		String paypass = (String) map.get("paypass");
		String email = (String) map.get("email");
		Account account = accountDAO.findAccountBySign(email);
		if (account != null) {
			throw MySpaceException.REGISTER_EMAIL_DUPLICATED;
		}
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		account = accountDAO.getAccountById(accountId);
		String loginPassword = account.getLoginPassword();
		String payPassword = account.getPayPassword();
		if (loginPassword == null)
			loginPassword = UniqueIdentityUtil.createLoginPass();
		if (payPassword == null)
			payPassword = UniqueIdentityUtil.createPayPass();
		if (loginPassword == null || payPassword == null)
			activeCode = "a" + activeCode;
		else
			activeCode = "m" + activeCode;
		if (!payPassword.equals(SecurityUtil.encryptoMD5String(paypass)))
			throw MySpaceException.PAYPASS_ERROR;
		account.setEmStatus("2");
		account.setEmail(email);
		account.setActiveCode(activeCode);
		account.setUpdateUser(String.valueOf(accountId));
		account.setUpdateTime(new Date());
		accountDAO.updateAccount(account);
		StringBuffer activeURL = new StringBuffer();
		activeURL.append(urlPath);
		activeURL.append("/activate.do");
		if (activeURL.indexOf("?") == -1)
			activeURL.append("?");
		else
			activeURL.append("&");
		activeURL.append("email=" + email);
		activeURL.append("&");
		activeURL.append("activeCode=" + activeCode);
		EmailActive ea = (EmailActive) IPBAppFactory.getObj("emActive");
		ea.setAccount(email);
		ea.setActiveURL(activeURL.toString());
		ea.setUrlpath(urlPath);
		ea.setActiveCode(activeCode);
		ea.setAc(account);
		ea.sendMail(null, null);
	}

	public void sendActivateMailAfterRegister(String url, String email,
			Long accountId, String project) throws BusinessException {
		Account account = accountDAO.findAccountBySign(email);
		if (account != null)
			throw BusinessException.REGISTER_ACCOUNT_DUPLICATED;
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		account = accountDAO.getAccountById(accountId);
		String loginPassword = account.getLoginPassword();
		String payPassword = account.getPayPassword();
		if (loginPassword == null)
			loginPassword = UniqueIdentityUtil.createLoginPass();
		if (payPassword == null)
			payPassword = UniqueIdentityUtil.createPayPass();
		if (loginPassword == null || payPassword == null)
			activeCode = "a" + activeCode;
		else
			activeCode = "m" + activeCode;
		account.setStatus("2");
		account.setEmail(email);
		account.setActiveCode(activeCode);
		account.setUpdateUser(String.valueOf(accountId));
		account.setUpdateTime(new Date());
		accountDAO.updateAccount(account);
		VNVMail mail = VNVMail.createActivateMail(url, email, activeCode,
				loginPassword, payPassword, project);
		notificationService.sendMail(mail);
	}

	public void cancelMail(Map map) throws MySpaceException {
		String mobcode = (String) map.get("mobcode");
		Long accountId = (Long) map.get("accountId");
		Account ac = accountDAO.getAccountById(accountId);
		if (!mobcode.equals(ac.getMobActiveCode())) {
			throw MySpaceException.MOBILE_ACTIVECODE_ERROR;
		} else {
			ac.setEmail("");
			ac.setActiveCode("");
			ac.setEmStatus("1");
			ac.setUpdateUser(String.valueOf(accountId));
			ac.setUpdateTime(new Date());
			accountDAO.updateAccount(ac);
			return;
		}
	}

	public void cancelMobile(Map map) throws MySpaceException {
		String activeCode = (String) map.get("activeCode");
		Long accountId = (Long) map.get("accountId");
		Account ac = accountDAO.getAccountById(accountId);
		if (!activeCode.equals(ac.getActiveCode())) {
			throw MySpaceException.MOBILE_ACTIVECODE_ERROR;
		} else {
			ac.setMobile("");
			ac.setMobActiveCode("");
			ac.setMobStatus("1");
			ac.setUpdateUser(String.valueOf(accountId));
			ac.setUpdateTime(new Date());
			accountDAO.updateAccount(ac);
			return;
		}
	}

	public void sendCancelMail(Map map) throws MySpaceException {
		String urlPath = (String) map.get("urlPath");
		Long accountId = (Long) map.get("accountId");
		String describe = (String) map.get("describe");
		Account ac = accountDAO.getAccountById(accountId);
		String email = ac.getEmail();
		String cancelCode = UniqueIdentityUtil.getUserActiveCode();
		ac.setActiveCode(cancelCode);
		accountDAO.updateAccount(ac);
		EmailCancel ec = (EmailCancel) IPBAppFactory.getObj("emCancel");
		ec.setUrlPath(urlPath);
		ec.setEmail(email);
		ec.setCancelCode(cancelCode);
		ec.setDescribe(describe);
		StringBuffer cancelUrl = new StringBuffer();
		cancelUrl.append(urlPath);
		cancelUrl.append("/page/myspace/toCancel.do");
		if (cancelUrl.indexOf("?") == -1)
			cancelUrl.append("?");
		else
			cancelUrl.append("&");
		cancelUrl.append("email=" + email);
		cancelUrl.append("&");
		cancelUrl.append("cancelCode=" + cancelCode);
		ec.setCancelUrl(cancelUrl.toString());
		ec.setAccount(ac);
		ec.sendMail(null, null);
	}

	/**
	 * 注册手机号码后，开通email,发激活信
	 */
	public void sendActivateMailAfterRegister(String email, Long accountId,
			String project) throws BusinessException {
		Account account = accountDAO.findAccountBySign(email);
		if (account != null)
			throw BusinessException.REGISTER_ACCOUNT_DUPLICATED;
		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		account = accountDAO.getAccountById(accountId);
		String loginPassword = account.getLoginPassword();
		String payPassword = account.getPayPassword();
		if (loginPassword == null)
			loginPassword = UniqueIdentityUtil.createLoginPass();
		if (payPassword == null)
			payPassword = UniqueIdentityUtil.createPayPass();
		if (loginPassword == null || payPassword == null)
			activeCode = "a" + activeCode;
		else
			activeCode = "m" + activeCode;
		account.setStatus("2");
		account.setEmail(email);
		account.setActiveCode(activeCode);
		account.setUpdateUser(String.valueOf(accountId));
		account.setUpdateTime(new Date());
		accountDAO.updateAccount(account);
		VNVMail mail = VNVMail.createActivateMail(email, activeCode,
				loginPassword, payPassword, project);
		notificationService.sendMail(mail);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.agiledata.bank.account.service.impl.III#sendActivateMail(java.lang.String)
	 */
	public void sendActivateMail(String url, String email, String project)
			throws BusinessException {
		if (DataTypeUtil.isEmptyString(email)) {
			throw BusinessException.INFORMAL_FORM;
		}
		Account account = this.accountDAO.findAccountBySign(email);

		if (account == null) {
			throw BusinessException.ACTIVATE_ACCOUNT_NOT_EXIST;
		}

		if (Constant.ACCOUNT_STATE_NORMAL.equals(account.getEmStatus())) {
			throw BusinessException.ACTIVATE_ACCOUNT_USING;
		}

		String loginPass = UniqueIdentityUtil.createLoginPass();
		String payPass = UniqueIdentityUtil.createPayPass();

		String activeCode = UniqueIdentityUtil.getUserActiveCode();
		account.setActiveCode(activeCode);
		this.accountDAO.updateAccount(account);
		VNVMail mail = VNVMail.createActivateMail(url, email, activeCode,
				loginPass, payPass, project);
		this.notificationService.sendMail(mail);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.agiledata.bank.account.service.impl.III#sendPasswordMail(java.lang.String)
	 */
	public void sendPasswordMail(String email) throws BusinessException {
		if (StringUtil.isStrEmpty(email)) { // email为空
			throw BusinessException.INFORMAL_FORM;
		}
		Account account = this.accountDAO.findAccountBySign(email);

		if (account == null) {
			throw BusinessException.ACTIVATE_ACCOUNT_NOT_EXIST;
		}

		String loginPass = UniqueIdentityUtil.createLoginPass();
		String payPass = UniqueIdentityUtil.createPayPass();

		account.setLoginPassword(SecurityUtil.encryptoMD5String(loginPass));
		account.setPayPassword(SecurityUtil.encryptoMD5String(payPass));

		this.accountDAO.updateAccount(account);

		VNVMail mail = VNVMail.createPasswordMail(email, loginPass, payPass);
		this.notificationService.sendMail(mail);

	}

	// 用户申请重置密码，系统给该用户发送邮件，告知其确认码（确认码保存在account表resetPwdCode字段）
	public void sendResetPasswordCodeMail(String email, String pwdType)
			throws MySpaceException {
		Account account = this.accountDAO.findAccountBySign(email);

		if (account == null) {
			throw BusinessException.RESET_PWD_ACCOUNT_NOT_EXIST;
		}

		String resetCode = UniqueIdentityUtil.getUserActiveCode();
		String code = pwdType + ",e," + resetCode;
		account.setResetPwdCode(code);

		this.accountDAO.updateAccount(account);

		String passwordType = "";
		if (pwdType.equals(IAccountConst.RESET_PWD_TYPE_LOGIN)) {
			passwordType = "登录";
		} else if (pwdType.equals(IAccountConst.RESET_PWD_TYPE_PAY)) {
			passwordType = "支付";
		} else if (pwdType.equals(IAccountConst.RESET_PWD_TYPE_IVR_LOGIN)) {
			passwordType = "电话账户登录";
		} else if (pwdType.equals(IAccountConst.RESET_PWD_TYPE_IVR_PAY)) {
			passwordType = "电话账户支付";
		}

		VNVMail mail = new VNVMail();
		mail.setTemplateName("mail-applyResetPassword.vm");
		mail.setEmailTo(email);
		mail.setSubject("您申请重置账号" + passwordType + "密码");

		Map ctx = new HashMap();
		ctx.put("account", email);
		ctx.put("passwordType", passwordType);
		ctx.put("resetCode", resetCode);
		ctx.put("now", DateUtil.date2String(Calendar.getInstance().getTime()));
		mail.setContext(ctx);

		this.notificationService.sendMail(mail);
	}

	// 重置登录密码，并将resetPwdCode字段清空
	public void resetLoginPassword(long accountId, String pass)
			throws MySpaceException {
		Account account = this.accountDAO.getAccountById(new Long(accountId));

		if (account == null) {
			throw BusinessException.RESET_PWD_ACCOUNT_NOT_EXIST;
		}

		account.setLoginPassword(SecurityUtil.encryptoMD5String(pass));
		account.setResetPwdCode(null);

		this.accountDAO.updateAccount(account);
	}

	// 判断是否冻结账户
	public boolean lockAccount(Long accountId) throws BusinessException {
		Account account = accountDAO.getAccountById(accountId);
		if (Constant.ACCOUNT_STATE_LOCK.equals(account.getStatus())) {
			// //账户冻结
			// throw BusinessException.LOGON_ACCOUNT_LOCK ;
			return true;
		} else {
			return false;
		}
	}

	/**
	 * @return Returns the accountDAO.
	 */
	public IAccountDAO getAccountDAO() {
		return accountDAO;
	}

	/**
	 * @param accountDAO
	 *            The accountDAO to set.
	 */
	public void setAccountDAO(IAccountDAO accountDAO) {
		this.accountDAO = accountDAO;
	}

	public void afterPropertiesSet() throws Exception {

	}

	/**
	 * @param notificationService
	 *            The notificationService to set.
	 */
	public void setNotificationService(IMailService notificationService) {
		this.notificationService = notificationService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.agiledata.bank.account.service.impl.III#getBankBySubaccountId(long)
	 */
	public List getBankBySubaccountId(long subaccountId) {
		List banklist = this.accountDAO.findBanksOfSubaccountId(new Long(
				subaccountId));
		List nBankList = new ArrayList();
		Iterator itbl = banklist.iterator();
		AccountBank defaultAB = new AccountBank();

		while (itbl.hasNext()) {
			AccountBank ab = (AccountBank) itbl.next();
			if (ab.getDefaultFlag().equals("Y")) {
				defaultAB = ab;
				nBankList.add(0, defaultAB);
				banklist.remove(defaultAB);
				break;
			}
		}
		nBankList.addAll(banklist);
		return nBankList;
	}

	public List findTransHisByPara(long email, String startTime, String endTime)
			throws BusinessException {

		CapitalDetailBean detail = null;
		List list = this.accountDAO.findTransHisByPara(email, startTime,
				endTime);
		List returnList = new ArrayList();
		if (list == null || list.size() < 1) {
			return null;
		} else {
			for (int i = 0; i < list.size(); i++) {
				detail = new CapitalDetailBean();
				Object[] obj = (Object[]) list.get(i);
				if (obj[0] != null) {
					detail.setOrderId(obj[0].toString());
				}
				if (obj[1] != null) {
					detail.setTransId(obj[1].toString());
				}
				if (obj[2] != null) {
					detail.setId(Long.valueOf(obj[2].toString()));
				}
				if (obj[3] != null) {
					detail.setAmount(Double.valueOf(obj[3].toString()));
				}
				if (obj[4] != null) {
					detail.setActionSeq((Long.valueOf(obj[4].toString())));
				}
				if (obj[5] != null) {
					detail.setTransStatus(obj[5].toString());
				}
				if (obj[6] != null) {
					DateFormat format = new SimpleDateFormat(
							"yyyy-MM-dd hh:mm:ss");
					try {
						Date date = format.parse(obj[6].toString());
						detail.setCreateTime(date);
					} catch (ParseException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				if (obj[7] != null) {
					detail.setReturnAmount(Double.valueOf(obj[7].toString()));
				}
				if (obj[8] != null) {
					detail.setRemark((obj[8].toString()));
				}
				returnList.add(detail);
			}
		}
		return returnList;
	}

	public List getAccountBanksByAccountId(long accountId) {
		List banklist = this.accountDAO.getAccountBanksByAccountId(accountId);
		List nBankList = new ArrayList();
		Iterator itbl = banklist.iterator();
		AccountBank defaultAB = new AccountBank();

		while (itbl.hasNext()) {
			AccountBank ab = (AccountBank) itbl.next();
			if (ab.getDefaultFlag().equals("Y")) {
				defaultAB = ab;
				nBankList.add(0, defaultAB);
				banklist.remove(defaultAB);
				break;
			}
		}
		nBankList.addAll(banklist);
		return nBankList;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * cn.agiledata.bank.account.service.impl.III#findAccountByEmail(java.lang.String
	 * )
	 */
	public Account findAccountByEmail(String sign) throws BusinessException {
		return this.accountDAO.findAccountBySign(sign);
	}

	public QdTransDetail findDetailByOrderId(String orderId) {
		QdTransDetail detail = null;
		List list = this.accountDAO.findDetailByOrderId(orderId);
		if (list == null || list.size() < 1) {
			return null;
		} else {
			detail = new QdTransDetail();
			Object[] obj = (Object[]) list.get(0);
			if (obj[0] != null) {
				detail.setOrderId(obj[0].toString());
			}
			if (obj[1] != null) {
				detail.setTransId(obj[1].toString());
			}
			if (obj[2] != null) {
				detail.setId(Long.valueOf(obj[2].toString()));
			}
			if (obj[3] != null) {
				detail.setAmount(Double.valueOf(obj[3].toString()));
			}
			if (obj[4] != null) {
				detail.setActionSeq((Long.valueOf(obj[4].toString())));
			}
			if (obj[5] != null) {
				detail.setTransStatus(obj[5].toString());
			}
			if (obj[6] != null) {
				DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
				try {
					Date date = format.parse(obj[6].toString());
					detail.setCreateTime(date);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if (obj[7] != null) {
				detail.setReturnAmount(Double.valueOf(obj[7].toString()));
			}
			if (obj[8] != null) {
				detail.setRemark((obj[8].toString()));
			}
			if (obj[9] != null) {
				detail.setCreditSeq(Long.valueOf(obj[9].toString()));
			}
		}
		return detail;
	}

	public void saveOrUpdateTransDetail(QdTransDetail detail) {
		this.accountDAO.saveOrUpdateTransDetail(detail);
	}

	public Account findAccountByEmailAvaible(String sign)
			throws BusinessException {
		return this.accountDAO.findAccountBySignAvaible(sign);
	}

	public Account findAccountByMobile(String sign) throws BusinessException {
		return this.accountDAO.findAccountBySign(sign);
	}

	public SubAccount findSubAccountBalance(long AccountId, String subAccountId) {
		return this.accountDAO.findBalance(AccountId, subAccountId);
	}

	public void setAuthenticateService(AuthenticateService authenticateService) {
		this.authenticateService = authenticateService;
	}

	public void setAhoi(AccountHistoryObserverInter ahoi) {
		this.ahoi = ahoi;
	}

	// 当支付密码输错时记入系统日志
	public void writeSystemLogWhenPayPasswordError(Account account, String ip) {
		SystemLog sysLog = new SystemLog();
		sysLog.setAccount(account);
		sysLog.setAccountName(account.getName());
		sysLog.setAccountId(account.getAccountId());
		// request.getRemoteAddr()
		if (ip == null)
			ip = "payPwdErr";
		sysLog.setLoginIp(ip);
		sysLog.setLoginTime(new Date());
		sysLog.setLoginErrReason(Constant.PAY_PWD_ERR);
		sysLog.setRemark(Constant.PAY_PWD_ERR_REMARK);
		this.accountDAO.updateLog(sysLog);
	}

	// 获取账户当日支付密码输错次数
	public int getCurrentPayPwdErrByAccountId(Long accountId) {
		return this.accountDAO.getCurrentPayPwdErrByAccountId(accountId);
	}

	// 获取系统允许的当日支付密码累计输错次数上限(大于这个值就锁定该账户，明日才能登录)
	public int getMaxPayPwdErrFromSysBook() {
		return this.accountDAO.getMaxPayPwdErrFromSysBook();
	}

	// 锁定账户(明日才能登录)
	public void lockAccountLoginBySign(String emailOrMobile) {
		this.accountDAO.lockAccountLoginBySign(emailOrMobile);
	}

	// 黑名单用户禁止登录 add by mxb 20120916
	public boolean checkBlackList(String email) throws BusinessException {

		return this.accountDAO.checkBlackList(email);

	}

	public AuditOperandType getAuditOperandType() {
		return this.auditService.getAuditOperandType(AUDIT_OPERAND_CLASS,
				ACTION_FLAG_ACCOUNTCOMPANY_AUTHENTICATION);
	}

	// 修改确认金额
	public String modifyAmount(Map form) throws MySpaceException {
		Long accountId = (Long) form.get("accountId");
		String amount = (String) form.get("amount");
		Account account = accountDAO.getAccountById(accountId);
		account.setIvrLoginPassword(amount);
		accountDAO.updateAccount(account);
		return "";
	}

	public Object statQdTransDetail(Long id, String ruleId) throws Exception {
		QdTransDetail qd = new QdTransDetail();
		StringBuffer sb = new StringBuffer();
		List list = new ArrayList();
		list.add(Constant.CODE_14);
		list.add(Constant.CODE_15);
		if (list.contains(ruleId)) {
			sb.append(" select count(*) ");
		} else {
			sb.append(" select sum(returnAmount) ");
		}
		sb
				.append(" from QdTransDetail qd where qd.transStatus not in(?,?,?) and qd.creditSeq = ?");
		String param1 = Constant.TRANS_FAIL2 + "," + Constant.TRANS_FAIL + ","
				+ Constant.REFUND_OK;
		Calendar calendar = Calendar.getInstance();
		sb.append(" and qd.createTime <= ?  and qd.createTime>= ?");
		Date param2 = null;
		Date param3 = null;
		list = new ArrayList();
		list.add(Constant.CODE_16);
		list.add(Constant.CODE_15);
		if (list.contains(ruleId)) {
			calendar.set(Calendar.DAY_OF_MONTH, 1);
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			param2 = calendar.getTime();
			calendar.set(Calendar.DAY_OF_MONTH, calendar
					.getActualMaximum(Calendar.DAY_OF_MONTH));
			calendar.set(Calendar.HOUR_OF_DAY, 23);
			calendar.set(Calendar.MINUTE, 59);
			calendar.set(Calendar.SECOND, 59);
			calendar.set(Calendar.MILLISECOND, 999);
			param3 = calendar.getTime();
		}
		list = new ArrayList();
		list.add(Constant.CODE_13);
		list.add(Constant.CODE_14);
		if (list.contains(ruleId)) {
			calendar.set(Calendar.HOUR_OF_DAY, 0);
			calendar.set(Calendar.MINUTE, 0);
			calendar.set(Calendar.SECOND, 0);
			calendar.set(Calendar.MILLISECOND, 0);
			param2 = calendar.getTime();
			calendar.set(Calendar.HOUR_OF_DAY, 23);
			calendar.set(Calendar.MINUTE, 59);
			calendar.set(Calendar.SECOND, 59);
			calendar.set(Calendar.MILLISECOND, 999);
			param3 = calendar.getTime();
		}
		Object[] params = new Object[] { Constant.TRANS_FAIL2,
				Constant.TRANS_FAIL, Constant.REFUND_OK, id, param3, param2 };

		return accountDAO.queryQdTrans(sb.toString(), params);
	}

	public List<MoneyRole> getRule() throws Exception {
		StringBuffer sb = new StringBuffer(
				"from MoneyRole mr where mr.code in (?,?,?,?,?) order by mr.code desc");
		String[] strs = new String[] { Constant.CODE_12, Constant.CODE_13,
				Constant.CODE_14, Constant.CODE_15, Constant.CODE_16 };
		return accountDAO.getRule(sb.toString(), strs);
	}

	public static void main(String[] args) {
		Calendar calendar = Calendar.getInstance();
		calendar.set(Calendar.DAY_OF_MONTH, 1);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		Date param2 = calendar.getTime();
		System.out.println(param2.toString());
		calendar.set(Calendar.DAY_OF_MONTH, calendar
				.getActualMaximum(Calendar.DAY_OF_MONTH));
		calendar.set(Calendar.HOUR_OF_DAY, 23);
		calendar.set(Calendar.MINUTE, 59);
		calendar.set(Calendar.SECOND, 59);
		calendar.set(Calendar.MILLISECOND, 999);
		Date param3 = calendar.getTime();
		System.out.println(param2.toString());
		System.out.println(param3.toString());
	}

	public void update(Account account) throws Exception {
		accountDAO.update(account);
	}

}
